package com.aiti.lulian.controller.gongxin;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.base.controller.WebController;
import com.aiti.base.core.exception.BusinessException;
import com.aiti.base.core.utils.message.Message;
import com.aiti.lulian.constant.GxmhConstant;
import com.aiti.lulian.dto.gonxin.BankDto;
import com.aiti.lulian.dto.gonxin.FundApplicationDto;
import com.aiti.lulian.dto.gonxin.FundDto;
import com.aiti.lulian.entity.excel.FundApplicationExport;
import com.aiti.lulian.entity.excel.FundExport;
import com.aiti.lulian.gxmh.dto.SysUserDto;
import com.aiti.lulian.handler.HeaderStyleHandler;
import com.aiti.lulian.mapper.gxmh.GxmhSysMapper;
import com.aiti.lulian.service.IBankService;
import com.aiti.lulian.service.IFundApplicationService;
import com.aiti.lulian.service.IFundService;
import com.aiti.lulian.vo.gongxin.BankVo;
import com.aiti.lulian.vo.gongxin.FundApplicationVo;
import com.aiti.lulian.vo.gongxin.FundVo;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "资金控制层")
@RestController
@RequestMapping("/fund")
@Slf4j
public class FundController extends WebController {

    @Autowired
    private IFundService fundService;

    @Autowired
    private IFundApplicationService fundApplicationService;

    @Autowired
    private IBankService bankService;

    @Autowired
    private GxmhSysMapper gxmhSysMapper;

    @ApiOperation("新增资金产品")
    @PostMapping
    public Message addFund(@RequestBody FundDto dto) {
        try {
            dto.setUserId(findUserId());
            fundService.addFund(dto);
            return Message.success();
        } catch (Exception e) {
            if(e instanceof BusinessException) {
                return Message.fail(e.getMessage());
            }
            log.error("新增资金产品异常：{}", ExceptionUtil.stacktraceToString(e));
            return Message.fail("接口异常："+ e.getMessage());
        }
    }

    @ApiOperation("查询资金产品列表")
    @GetMapping("/list")
    public Message getFundList(FundDto dto) {
        Page<FundVo> page = startPage();
        if (StrUtil.isBlank(dto.getUserId())) {
            dto.setUserId(findUserId());
            if (StrUtil.isBlank(dto.getUserId())) {
                return Fail("请先登录");
            }
        }
        List<FundVo> list = fundService.getList(page, dto);
        return Message.success(getPageResult(list, dto.getPageNum(), dto.getPageSize(), page.getTotal()));
    }

    @ApiOperation("查询资金产品详情")
    @GetMapping("/{baseId}")
    public Message getDetails(@PathVariable("baseId") String baseId) {
        FundVo fundVo = fundService.getDetails(baseId, findUserId());
        return Message.success(fundVo);
    }

    @ApiOperation("删除商品绑定的服务商用户")
    @DeleteMapping("/delServerUser")
    public Message deleteServerUser(@RequestParam("username") String username,
                                    @RequestParam("fundBaseId") String fundBaseId) {
        try {
            fundService.deleteServerUser(username, fundBaseId);
            return Message.success();
        }catch (Exception e) {
            if(e instanceof BusinessException) {
                return Message.fail(e.getMessage());
            }
            log.error("删除服务商用户异常：{}", ExceptionUtil.stacktraceToString(e));
            return Message.fail("接口异常："+ e.getMessage());
        }
    }

    @ApiOperation("编辑资金产品")
    @PutMapping
    public Message updateFund(@RequestBody FundDto dto) {
        try {
            dto.setUpdateBy(findUserId());
            fundService.updateFund(dto);
            return Message.success();
        }catch (Exception e) {
            if(e instanceof BusinessException) {
                return Message.fail(e.getMessage());
            }
            log.error("编辑资金产品异常：{}", ExceptionUtil.stacktraceToString(e));
            return Message.fail("接口异常："+ e.getMessage());
        }
    }

    @ApiOperation("删除资金产品")
    @DeleteMapping
    public Message deleteFund(FundDto dto) {
        return fundService.deleteFund(dto);
    }

    @ApiOperation("资金申请表单提交")
    @PostMapping("/apply")
    public Message submitFundApplication(@RequestBody FundApplicationDto dto) {
        dto.setCreator(dto.getUserId());
        fundApplicationService.submitFundApplication(dto);
        return Message.success();
    }

    @ApiOperation("查询产品申请列表")
    @GetMapping("/application/list")
    public Message getApplicationList(FundApplicationDto dto) {
        Page<FundApplicationVo> page = startPage();
        dto.setUserId(findUserId());
        List<FundApplicationVo> list = fundApplicationService.getApplicationList(page, dto);
        return Message.success(getPageResult(list, dto.getPageNum(), dto.getPageSize(), page.getTotal()));
    }

    @ApiOperation("查询产品申请详情")
    @GetMapping("/application/{baseId}")
    public Message getApplicationDetails(@PathVariable("baseId") String baseId) {
        FundApplicationVo fundApplicationVo = fundApplicationService.getApplicationDetails(baseId);
        return Message.success(fundApplicationVo);
    }

    @ApiOperation("删除产品申请")
    @DeleteMapping("/application")
    public Message deleteFundApplication(FundApplicationDto dto) {
        fundApplicationService.deleteFundApplication(dto);
        return Message.success();
    }

    @ApiOperation("新增银行")
    @PostMapping("/bank")
    public Message addBank(@RequestBody BankDto dto) {
        dto.setCreator(findUserId());
        bankService.addBank(dto);
        return Message.success();
    }

    @ApiOperation("查询银行列表")
    @GetMapping("/bank/list")
    public Message getBankList(BankDto dto) {
        Page<BankVo> page = startPage();
        List<BankVo> list = bankService.getBankList(page, dto);
        return Message.success(getPageResult(list, dto.getPageNum(), dto.getPageSize(), page.getTotal()));
    }

    @ApiOperation("查询银行详情")
    @GetMapping("/bank/{baseId}")
    public Message getBankDetails(@PathVariable("baseId") String baseId) {
        BankVo bankVo = bankService.getBankDetails(baseId);
        return Message.success(bankVo);
    }

    @ApiOperation("编辑银行")
    @PutMapping("/bank")
    public Message updateBank(@RequestBody BankDto dto) {
        dto.setUpdateBy(findUserId());
        bankService.updateBank(dto);
        return Message.success();
    }

    @ApiOperation("删除银行")
    @DeleteMapping("/bank")
    public Message deleteBank(BankDto dto) {
        return bankService.deleteBank(dto);
    }

    @ApiOperation("下载资金产品导入模版")
    @GetMapping("/importTemplate/download")
    public void downloadFundImportTemplate(HttpServletResponse response) {
        FileInputStream fileInputStream = null;
        ServletOutputStream outputStream = null;
        try {
            // 设置文件路径
//            String filePath = "/Volumes/WorkDisk/ShanDongZhiZao/workspace/template/工信门户-资金产品导入模版.xlsx";
            String filePath = "/home/services/template/工信门户-资金产品导入模版.xlsx";
//            String filePath = "C:\\Users\\Administrator\\Desktop\\工信门户-资金产品导入模版.xlsx";
            File downloadFile = new File(filePath);

            // 设置文件名（响应头中的推荐文件名）
            String fileName = "资金产品导入模版.xlsx";

            // 对文件名进行URL编码
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");

            // 设置响应头
            response.setContentType("application/octet-stream");
//            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);

            // 设置文件大小
            response.setContentLength((int) downloadFile.length());

            // 通过文件输入流读取文件内容
            fileInputStream = new FileInputStream(downloadFile);

            // 通过ServletOutputStream将文件内容写入HTTP响应
            outputStream = response.getOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            // 关闭流资源
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception e) {
            logger.error("下载资金产品导入模版异常：===》" + e);
        }
    }

    @ApiOperation("批量导入资金产品")
    @PostMapping("/importBatch")
    public Message importFundBatch(@RequestPart("file") MultipartFile file) {
        try {
            String userId = findUserId();
            if (StrUtil.isBlank(userId)) {
                return Fail("请先登录");
            }
            if (file == null) {
                return Fail("请上传文件");
            }
            String contentType = file.getContentType();
            String originalFilename = file.getOriginalFilename();
            if (! ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(contentType)
                    && originalFilename != null && originalFilename.endsWith(".xlsx"))) {
                return Fail("请上传xlsx格式的文件");
            }
            return fundService.importBatch(file, userId);
        } catch (Exception e) {
            logger.error("导入异常：===》" + e);
            return Fail(e.getMessage());
        }
    }

    @ApiOperation("导出资金产品列表")
    @GetMapping("/list/export")
    public Message exportFundList(HttpServletResponse response, FundDto dto) {
        try {
            dto.setUserId(findUserId());
            List<FundVo> list = fundService.getList(null, dto);
            List<FundExport> fundExportList = list.stream().map(i -> {
                FundExport fundExport = new FundExport();
                BeanUtils.copyProperties(i, fundExport);
                fundExport.setBaseCreateTimeStr(new SimpleDateFormat("yyyy-MM-dd").format(i.getBaseCreateTime()));
                return fundExport;
            }).collect(Collectors.toList());

            // 设置响应头，确保浏览器以下载方式处理文件
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            // 设置文件名，注意需要对中文进行 URL 编码
            String fileName = URLEncoder.encode("产品列表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + fileName + ".xlsx\";" +
                            " filename*=UTF-8''" + fileName + ".xlsx");

            // 使用 EasyExcel 写入数据到输出流
            OutputStream outputStream =  response.getOutputStream();
            EasyExcel.write(outputStream, FundExport.class)
                    .sheet("产品列表")
                    .registerWriteHandler(new HeaderStyleHandler())
                    .doWrite(fundExportList);

            // 关闭流资源
            if (outputStream != null) {
                outputStream.close();
            }

            return Message.success();
        } catch (Exception e) {
            logger.error("导出异常：===》" + e);
            return Message.fail(e.getMessage());
        }
    }

    @ApiOperation("导出资金产品申请列表")
    @GetMapping("/application/list/export")
    public Message exportFundApplicationList(HttpServletResponse response, FundApplicationDto dto) {
        try {
            dto.setUserId(findUserId());
            List<FundApplicationVo> list = fundApplicationService.getApplicationList(null, dto);
            List<FundApplicationExport> fundApplicationExportList = list.stream().map(i -> {
                FundApplicationExport fundApplicationExport = new FundApplicationExport();
                BeanUtils.copyProperties(i, fundApplicationExport);
                return fundApplicationExport;
            }).collect(Collectors.toList());

            // 设置响应头，确保浏览器以下载方式处理文件
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            // 设置文件名，注意需要对中文进行 URL 编码
            String fileName = URLEncoder.encode("产品申请列表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + fileName + ".xlsx\";" +
                            " filename*=UTF-8''" + fileName + ".xlsx");

            // 使用 EasyExcel 写入数据到输出流
            OutputStream outputStream =  response.getOutputStream();
            EasyExcel.write(outputStream, FundApplicationExport.class)
                    .sheet("产品申请列表")
                    .registerWriteHandler(new HeaderStyleHandler())
                    .doWrite(fundApplicationExportList);

            // 关闭流资源
            if (outputStream != null) {
                outputStream.close();
            }

            return Message.success();
        } catch (Exception e) {
            logger.error("导出异常：===》" + e);
            return Message.fail(e.getMessage());
        }
    }

    @ApiOperation("判断用户是否是服务商用户")
    @GetMapping("/isServerUser")
    public Message isServerUser() {
        SysUserDto sysUserDto = gxmhSysMapper.queryUserInfo(findUserId());
        if(sysUserDto == null) {
            return Message.fail("用户不存在");
        }
        if(StrUtil.isBlank(sysUserDto.getSource())) {
            return Message.success(false);
        }
        return Message.success(GxmhConstant.GXMH_SERVER_USER_FLAG.equals(sysUserDto.getSource()));
    }
}
